package com.brillilab.service.core.kit.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.brillilab.domain.enums.kit.KitEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.dao.mapper.kit.ReagentTypeHideMapper;
import com.brillilab.dao.mapper.kit.ReagentTypeMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.common.IsDeleteEnum;
import com.brillilab.domain.po.kit.Reagent;
import com.brillilab.domain.po.kit.ReagentType;
import com.brillilab.domain.po.kit.ReagentTypeHide;
import com.brillilab.domain.vo.inventory.ReagentTypeInventoryCount;
import com.brillilab.domain.vo.kit.ReagentTypeVo;
import com.brillilab.service.core.kit.IKitService;
import com.brillilab.service.core.kit.IReagentService;
import com.brillilab.service.core.kit.IReagentTypeService;
import com.brillilab.service.core.kit.ISampleTemplateService;

@Service
@Transactional
public class ReagentTypeServiceImpl implements IReagentTypeService {

    @Resource
    private ReagentTypeHideMapper reagentTypeHideMapper;
    @Resource
    private ReagentTypeMapper reagentTypeMapper;
    @Resource
    private IKitService kitService;
    @Resource
    private IReagentService reagentService;
    @Resource
    private ISampleTemplateService sampleTemplateService;


    @Override
    public ReagentType insert(ReagentType entity) {
        if (entity.getClassify() == 1) {
            Assert.isTrue(entity.getParentId() != null, "一类型ID不能为NULL");
            LambdaQueryWrapper<ReagentType> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ReagentType::getLabId, entity.getLabId());
            wrapper.eq(ReagentType::getParentId, entity.getParentId());
            wrapper.eq(ReagentType::getIsDelete, IsDeleteEnum.NO.getValue());
            Integer count = reagentTypeMapper.selectCount(wrapper);
            Assert.isTrue(count < 40, "试剂类型已超出限制40个");

            Integer insert = reagentTypeMapper.insert(entity);
            Assert.isTrue(insert == 1, "添加失败");
        } else if (entity.getClassify() == 2) {
            entity.setParentId(null);
            entity.setIsSystemHide(1);
            Integer insert = reagentTypeMapper.insert(entity);
            this.isHideType(entity.getLabId(), entity.getId(), 0, entity.getLabMemberId());
            Assert.isTrue(insert == 1, "添加失败");
            sampleTemplateService.addGroup(entity.getLabId(), entity.getId(), entity.getLabMemberId());
        }
        return entity;
    }

    @Override
    public boolean deleteById(Long id) {
        Assert.notNull(id, "删除ID不能为空");
        ReagentType entity = new ReagentType();
        entity.setId(id);
        entity.setIsDelete(IsDeleteEnum.YES.getValue());
        return this.updateById(entity);
    }

    @Override
    public boolean updateById(ReagentType entity) {
        entity.setUpdateTime(new Date());
        Integer b = reagentTypeMapper.updateById(entity);
        return b == 1 ? true : false;
    }

    @Override
    public ReagentType selectById(Long id) {
        return reagentTypeMapper.selectById(id);
    }

    @Override
    public List<ReagentTypeVo> getTypeList(Integer classify, Long labId, Long labMemberId) {
        List<ReagentTypeVo> listVo = reagentTypeMapper.selectOneType(classify, labId, labMemberId);
        if (listVo != null && listVo.size() > 0) {
            // 分组统计分类下试剂数量2
            Map<Long, Long> numMap = kitService.groupByReagentType(labId, classify);
            if (classify == 1) {
                // 获取分组二级分类
                Map<Long, List<ReagentTypeVo>> typeMap = reagentTypeMapper.selectAllSuReagentType(labId, classify, labMemberId,false)
                        .stream().collect(Collectors.groupingBy(ReagentTypeVo::getParentId));
                listVo.forEach(typeVo -> {
                    //子分类列表
                    List<ReagentTypeVo> suList = typeMap.get(typeVo.getReagentTypeId());
                    if (suList != null) {
                        suList.forEach(suVo -> suVo.setIsHave(numMap.get(suVo.getReagentTypeId())));
                        // 设置分类下是否有试剂
                        typeVo.setReagentTypeList(suList);
                    }
                });
            }
        }
        return listVo;
    }

    @Override
    public List<ReagentTypeVo> getTypeList(Long labId, Long labMemberId) {
        return reagentTypeMapper.selectReagentType(null, labId, labMemberId);
    }

    @Override
    public List<ReagentTypeInventoryCount> getTypeInventoryCount(Long labId, Long rootTypeId) {
        return reagentTypeMapper.getTypeInventoryCount(labId, rootTypeId);
    }

    @Override
    public List<ReagentTypeVo> selectAllSuReagentType(Long labId, Integer classify, Long labMemberId,Boolean isDelete) {
        return reagentTypeMapper.selectAllSuReagentType(labId, classify, labMemberId,isDelete);
    }

    @Override
    public boolean isHideType(Long labId, Long reagentTypeId, Integer isHide, Long labMemberId) {
        LambdaQueryWrapper<ReagentTypeHide> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ReagentTypeHide::getLabId, labId);
        wrapper.eq(ReagentTypeHide::getLabMemberId, labMemberId);
        wrapper.eq(ReagentTypeHide::getReagentTypeId, reagentTypeId);
        ReagentTypeHide typeHide = reagentTypeHideMapper.selectOne(wrapper);
        if (typeHide != null) {
            typeHide.setIsHide(isHide);
            int i = reagentTypeHideMapper.updateById(typeHide);
            return i == 1 ? true : false;
        } else {
            typeHide = new ReagentTypeHide();
            typeHide.setLabId(labId);
            typeHide.setLabMemberId(labMemberId);
            typeHide.setReagentTypeId(reagentTypeId);
            typeHide.setIsHide(isHide);
            int i = reagentTypeHideMapper.insert(typeHide);
            return i == 1 ? true : false;
        }
    }

    /**
     * 根据三级试剂类型Id查找一级试剂类型Id
     *
     * @param secondReagentTypeIds
     * @return
     */
    @Override
    public Map<Long, Long> selectFirstReagentTypeMap(List<Long> secondReagentTypeIds) {

        Map<Long, Long> secondFirstMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(secondReagentTypeIds)) {

            List<ReagentType> secondReagentTypes = reagentTypeMapper.selectList(
                    new LambdaQueryWrapper<ReagentType>()
                            .in(ReagentType::getId, secondReagentTypeIds));


            List<Long> firstReagentTypeIds = secondReagentTypes.stream().map(ReagentType::getParentId).distinct().collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(firstReagentTypeIds)) {

                List<ReagentType> firstReagentTypes = reagentTypeMapper.selectList(
                        new LambdaQueryWrapper<ReagentType>()
                                .in(ReagentType::getId, firstReagentTypeIds));

                for (ReagentType secondReagentType : secondReagentTypes) {
                    //若二级父类id为空，则直接返回当前Id
                    if (secondReagentType.getParentId() == null) {
                        secondFirstMap.put(secondReagentType.getId(), secondReagentType.getId());
                    } else {
                        for (ReagentType firstReagentType : firstReagentTypes) {
                            if (firstReagentType.getId().equals(secondReagentType.getParentId())) {
                                secondFirstMap.put(secondReagentType.getId(), firstReagentType.getId());
                            }
                        }
                    }
                }
            }
        }
        return secondFirstMap;
    }

    @Override
    public List<ReagentType> getPublicReagentTypeList() {
        LambdaQueryWrapper<ReagentType> query = new LambdaQueryWrapper<>();
        query.isNull(ReagentType::getLabId);
        query.eq(ReagentType::getTag, 0);
        return reagentTypeMapper.selectList(query);
    }

    @Override
    public List<ReagentType> selectList(Long labId, Long labMemberId) {
        return reagentTypeMapper.selectList(
                new LambdaQueryWrapper<ReagentType>()
                        .eq(ReagentType::getIsDelete, BoolEnum.FALSE.getValue())
                        .and(wrapper -> wrapper
                                .eq(ReagentType::getLabId, labId)
                                .or()
                                .isNull(ReagentType::getLabId))
                        .and(wrapper -> wrapper
                                .eq(ReagentType::getLabMemberId, labMemberId)
                                .or()
                                .isNull(ReagentType::getLabMemberId))
        );
    }

    @Override
    public List<ReagentType> selectLabReagentTypeList(Long labId) {
        return reagentTypeMapper.selectList(
                new LambdaQueryWrapper<ReagentType>()
                        .eq(ReagentType::getIsDelete, BoolEnum.FALSE.getValue())
                        .and(wrapper -> wrapper
                                .eq(ReagentType::getLabId, labId)
                                .or()
                                .isNull(ReagentType::getLabId))
        );
    }

	@Override
	public Map<Long, Long> getFirstReagentTypeMapByReagentIds(List<Long> reagentIds) {
		Map<Long, Long> map = new HashMap<Long, Long>();
		List<Reagent> reagentList = reagentService.selectByReagentIds(reagentIds);
		List<Long> reagentTypeIds = reagentList.stream().map(Reagent::getReagentTypeId).collect(Collectors.toList());
		Map<Long, Long> firstReagentTypeMap = this.selectFirstReagentTypeMap(reagentTypeIds);
		for (Reagent reagent : reagentList) {
			map.put(reagent.getId(), firstReagentTypeMap.get(reagent.getReagentTypeId()));
		}
		return map;
	}

    @Override
    public List<ReagentType> getSelectedPublicReagentTypeList(List<Long> seletedIdList) {
        LambdaQueryWrapper<ReagentType> query = new LambdaQueryWrapper<>();
        query.in(ReagentType::getId,seletedIdList);
        query.isNull(ReagentType::getLabId);
        return reagentTypeMapper.selectList(query);
    }

    @Override
    public List<ReagentTypeVo> getTopicReagentTypeList(Long labMemberId, Long labId) {
        List<ReagentTypeVo> listVo = reagentTypeMapper.selectOneType(KitEnum.Classify.REAGENT.getValue(), labId, labMemberId);
        if (listVo != null && listVo.size() > 0) {
            // 分组统计分类下试剂数量2
            Map<Long, Long> numMap = kitService.groupByReagentType(labId, KitEnum.Classify.REAGENT.getValue());
            // 获取分组二级分类
            Map<Long, List<ReagentTypeVo>> typeMap = reagentTypeMapper.selectAllSuReagentType(labId, KitEnum.Classify.REAGENT.getValue(), labMemberId,false)
                    .stream().collect(Collectors.groupingBy(ReagentTypeVo::getParentId));
            listVo.forEach(typeVo -> {
                //子分类列表
                List<ReagentTypeVo> suList = typeMap.get(typeVo.getReagentTypeId());
                if (suList != null) {
                    suList.forEach(suVo -> suVo.setIsHave(numMap.get(suVo.getReagentTypeId())));
                    // 设置分类下是否有试剂
                    typeVo.setReagentTypeList(suList);
                }
            });
        }
        return listVo;
    }
}
